package com.example.homeworkmutualevaluation.Component;

import com.example.homeworkmutualevaluation.Entity.Task;
import com.example.homeworkmutualevaluation.Service.SubmitService;
import com.example.homeworkmutualevaluation.Service.TaskService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

@Component
@Slf4j
public class ScheduledTaskController {
    public enum ScheduledTask {
        StartEvaluation, EndEvaluation
    }
    public Map<Integer, ScheduledFuture<?>> taskMap = new ConcurrentHashMap<>();
    @Resource
    private ThreadPoolTaskScheduler syncScheduler;
    @Resource
    private SubmitService submitService;
    @Resource
    private TaskService taskService;
    public boolean add(ScheduledTask todo, int homeworkid, Timestamp timestamp) {
        int key = switch (todo) {
            case StartEvaluation -> 2 * homeworkid;
            case EndEvaluation -> 2 * homeworkid + 1;
        };
        stopIfExists(key);
        //任务所需的执行时间（如果这是过去，则任务将立即执行，即尽快执行）
        Instant instant = Instant.ofEpochMilli(timestamp.getTime());
        ScheduledFuture<?> schedule = switch (todo) {
            case StartEvaluation -> syncScheduler.schedule(new StartEvaluation(homeworkid), instant);
            case EndEvaluation -> syncScheduler.schedule(new EndEvaluation(homeworkid), instant);
        };
        taskMap.put(key, schedule);
        return true;
    }

    public void stopIfExists(Integer key) {
        ScheduledFuture<?> scheduledFuture = taskMap.get(key);
        if (scheduledFuture != null) {
            scheduledFuture.cancel(false);
            taskMap.remove(key);
        }
    }
    private class StartEvaluation implements Runnable {
        private final int homeworkid;
        public StartEvaluation (int homeworkid) {
            this.homeworkid = homeworkid;
        }
        @Override
        public void run() {
            log.info("StartEvaluation homeworkid="+homeworkid);
            List<String> submitters = submitService.findAllSubmitter(homeworkid);
            if (submitters.size() == 1) taskService.insert(submitters.get(0), submitters.get(0), homeworkid);
            else if (submitters.size() > 1) {
                List<Integer> index = new ArrayList<>(submitters.size());
                for (int i = 0; i < submitters.size(); i++) index.add(i);
                Collections.shuffle(index);
                //重复批改的次数
                int number = Integer.min(5, submitters.size() - 1);
                List<Task> tasks = new ArrayList<>(submitters.size() * number);
                int evaluator = 0;
                for (int i = 0; i < submitters.size(); i++) {
                    for (int j = 0; j < number; j++) {
                        if (index.get(evaluator) != i)
                            tasks.add(new Task(submitters.get(index.get(evaluator)), submitters.get(i), homeworkid));
                        if (++evaluator >= index.size()) evaluator = 0;
                    }
                }
                taskService.insert(tasks);
            }
        }
    }
    private class EndEvaluation implements Runnable {
        private final int homeworkid;

        public EndEvaluation (int homeworkid) {
            this.homeworkid = homeworkid;
        }
        @Override
        public void run() {
            log.info("EndEvaluation homeworkid="+homeworkid);
            submitService.countScores(homeworkid);
        }
    }
}
